package com.geek.bams.server;

import com.geek.bams.entity.Account;

import javax.swing.*;
import java.awt.*;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;


public class ATMServer extends JFrame {
    
    private ServerSocket serverSocket;
    private boolean isRunning = false;
    private JButton startButton;
    private JButton shutdownButton;
    private JButton godModeButton;
    private JTextArea onlineUsersArea;
    private JLabel statusLabel;
    private JLabel onlineCountLabel;
    
    // 在线客户端列表（线程安全）
    private List<ClientInfo> onlineClients;
    
    // 账户ID到ClientInfo的映射（用于快速查找在线账户）
    private Map<Long, ClientInfo> accountToClientMap;
    
    // 账户ID到ServerTasker的映射（用于发送通知）
    private Map<Long, ServerTasker> accountToTaskerMap;
    
    // 定时刷新定时器
    private Timer refreshTimer;
    
    // 服务器端口号
    private static final int PORT = 8888;
    
    public ATMServer() {
        onlineClients = new CopyOnWriteArrayList<>(); // 线程安全的列表
        accountToClientMap = new ConcurrentHashMap<>(); // 线程安全的Map
        accountToTaskerMap = new ConcurrentHashMap<>(); // 线程安全的Map
        initComponents();
    }
    
    /**
     * 启动服务器
     */
    private void startServer() {
        if (isRunning) {
            JOptionPane.showMessageDialog(this, "服务器已在运行中！", "提示", JOptionPane.INFORMATION_MESSAGE);
            return;
        }
        
        try {
            // 创建服务器套接字，监听指定端口
            serverSocket = new ServerSocket(PORT);
            isRunning = true;
            
            // 更新UI状态
            startButton.setEnabled(false);
            shutdownButton.setEnabled(true);
            statusLabel.setText("服务器状态：运行中（端口：" + PORT + "）");
            appendLog("服务器启动成功，监听端口：" + PORT);
            
            // 启动定时刷新（每2秒刷新一次）
            startRefreshTimer();
            
            // 启动服务器线程，持续监听客户端连接
            new Thread(() -> {
                while (isRunning) {
                    try {
                        // 等待客户端连接（阻塞）
                        Socket clientSocket = serverSocket.accept();
                        String clientInfo = clientSocket.getRemoteSocketAddress().toString();
                        
                        // 创建客户端信息对象
                        ClientInfo clientInfoObj = new ClientInfo(clientSocket);
                        onlineClients.add(clientInfoObj);
                        
                        // 为每个客户端创建独立的处理线程
                        ServerTasker tasker = new ServerTasker(clientSocket, this, clientInfoObj);
                        tasker.start();
                        
                        SwingUtilities.invokeLater(() -> {
                            appendLog("客户端连接成功：" + clientInfo);
                            updateOnlineUsersDisplay();
                        });
                        
                    } catch (IOException e) {
                        if (isRunning) {
                            SwingUtilities.invokeLater(() -> {
                                appendLog("接受客户端连接时出错：" + e.getMessage());
                            });
                        }
                    }
                }
            }).start();
            
        } catch (IOException e) {
            JOptionPane.showMessageDialog(this, "服务器启动失败：" + e.getMessage(), "错误", JOptionPane.ERROR_MESSAGE);
            isRunning = false;
            startButton.setEnabled(true);
            shutdownButton.setEnabled(false);
            statusLabel.setText("服务器状态：未启动");
        }
    }
    
    /**
     * 关闭服务器
     */
    private void shutdownServer() {
        if (!isRunning) {
            JOptionPane.showMessageDialog(this, "服务器未运行！", "提示", JOptionPane.INFORMATION_MESSAGE);
            return;
        }
        
        isRunning = false;
        
        try {
            // 通知所有在线客户端服务器即将关闭
            // 遍历所有已登录的账户
            for (Map.Entry<Long, ServerTasker> entry : accountToTaskerMap.entrySet()) {
                ServerTasker tasker = entry.getValue();
                if (tasker != null) {
                    try {
                        tasker.sendServerShutdownNotification();
                    } catch (Exception e) {
                        // 忽略通知失败的情况
                    }
                }
            }
            
            if (serverSocket != null && !serverSocket.isClosed()) {
                serverSocket.close();
            }
            
            // 停止定时刷新
            stopRefreshTimer();
            
            // 清空在线客户端列表
            onlineClients.clear();
            accountToClientMap.clear();
            accountToTaskerMap.clear();
            
            // 更新UI状态
            startButton.setEnabled(true);
            shutdownButton.setEnabled(false);
            statusLabel.setText("服务器状态：已关闭");
            appendLog("服务器已关闭");
            updateOnlineUsersDisplay();
            
        } catch (IOException e) {
            JOptionPane.showMessageDialog(this, "关闭服务器时出错：" + e.getMessage(), "错误", JOptionPane.ERROR_MESSAGE);
        }
    }
    
    /**
     * 添加日志信息（供ServerTasker调用）
     * 注意：日志区域已移除，此方法现在只输出到控制台
     */
    public void appendLog(String message) {
        // 日志区域已移除，只输出到控制台
        System.out.println("[服务器日志] " + message);
    }
    
    /**
     * 注册ServerTasker（供ServerTasker调用）
     */
    public void registerTasker(Long accountId, ServerTasker tasker) {
        accountToTaskerMap.put(accountId, tasker);
    }
    
    /**
     * 客户端登录成功（供ServerTasker调用）
     */
    public void clientLoggedIn(ClientInfo clientInfo, Account account, ServerTasker tasker) {
        clientInfo.setAccount(account);
        // 添加到账户映射中
        accountToClientMap.put(account.getId(), clientInfo);
        accountToTaskerMap.put(account.getId(), tasker);
        SwingUtilities.invokeLater(() -> {
            String logMsg = String.format("客户端登录成功 - IP: %s | 账户ID: %d | 姓名: %s", 
                clientInfo.getIpAddress(), account.getId(), account.getName());
            appendLog(logMsg);
            updateOnlineUsersDisplay();
        });
    }
    
    /**
     * 客户端断开连接（供ServerTasker调用）
     */
    public void clientDisconnected(ClientInfo clientInfo) {
        onlineClients.remove(clientInfo);
        // 从账户映射中移除
        if (clientInfo.isLoggedIn() && clientInfo.getAccount() != null) {
            Long accountId = clientInfo.getAccount().getId();
            accountToClientMap.remove(accountId);
            accountToTaskerMap.remove(accountId);
        }
        SwingUtilities.invokeLater(() -> {
            if (clientInfo.isLoggedIn() && clientInfo.getAccount() != null) {
                String logMsg = String.format("客户端断开连接 - IP: %s | 账户ID: %d", 
                    clientInfo.getIpAddress(), clientInfo.getAccount().getId());
                appendLog(logMsg);
            } else {
                String logMsg = String.format("客户端断开连接 - IP: %s", clientInfo.getIpAddress());
                appendLog(logMsg);
            }
            updateOnlineUsersDisplay();
        });
    }
    
    /**
     * 通知指定账户的客户端刷新（供ServerTasker调用）
     * @param accountId 账户ID
     */
    public void notifyAccountRefresh(Long accountId) {
        ClientInfo clientInfo = accountToClientMap.get(accountId);
        if (clientInfo != null && clientInfo.getSocket() != null && !clientInfo.getSocket().isClosed()) {
            // 找到对应的ServerTasker并发送通知
            // 由于ServerTasker是线程，我们需要通过ServerTasker来发送消息
            // 这里我们标记需要刷新，让ServerTasker在下次通信时处理
            SwingUtilities.invokeLater(() -> {
                appendLog("通知账户 " + accountId + " 刷新账户信息");
            });
            // 实际的发送逻辑在ServerTasker中实现
        }
    }
    
    /**
     * 获取账户对应的ClientInfo
     */
    public ClientInfo getClientByAccountId(Long accountId) {
        return accountToClientMap.get(accountId);
    }
    
    /**
     * 获取账户对应的ServerTasker
     */
    public ServerTasker getTaskerByAccountId(Long accountId) {
        return accountToTaskerMap.get(accountId);
    }
    
    /**
     * 获取所有已登录的在线用户账户列表（供GodModePanel使用）
     */
    public java.util.List<com.geek.bams.entity.Account> getOnlineAccounts() {
        java.util.List<com.geek.bams.entity.Account> onlineAccounts = new java.util.ArrayList<>();
        com.geek.bams.dao.FileDao dao = new com.geek.bams.dao.FileDao();
        
        for (ClientInfo clientInfo : onlineClients) {
            if (clientInfo.isLoggedIn() && clientInfo.getAccount() != null) {
                // 从数据库重新获取最新账户信息（通过ID，不需要密码）
                try {
                    com.geek.bams.entity.Account account = dao.selectOne(clientInfo.getAccount().getId());
                    if (account != null) {
                        onlineAccounts.add(account);
                    }
                } catch (Exception e) {
                    // 如果获取失败，使用缓存的账户信息
                    onlineAccounts.add(clientInfo.getAccount());
                }
            }
        }
        return onlineAccounts;
    }
    
    /**
     * 更新在线用户显示
     */
    private void updateOnlineUsersDisplay() {
        // 更新在线人数
        int totalCount = onlineClients.size();
        int loggedInCount = 0;
        for (ClientInfo client : onlineClients) {
            if (client.isLoggedIn()) {
                loggedInCount++;
            }
        }
        onlineCountLabel.setText(String.format("总连接数: %d | 已登录: %d", totalCount, loggedInCount));
        
        // 更新在线用户列表
        onlineUsersArea.setText("");
        if (onlineClients.isEmpty()) {
            onlineUsersArea.append("暂无在线用户\n");
        } else {
            for (int i = 0; i < onlineClients.size(); i++) {
                ClientInfo client = onlineClients.get(i);
                onlineUsersArea.append(String.format("%d. %s\n", i + 1, client.getDisplayInfo()));
            }
        }
    }
    
    private void initComponents() {
        setTitle("BAMS 服务器端");
        setSize(900, 700);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setLocationRelativeTo(null);
        setResizable(true);
        
        // 创建主面板
        JPanel mainPanel = new JPanel(new BorderLayout());
        
        // 顶部状态栏
        JPanel topPanel = new JPanel(new BorderLayout());
        JPanel statusPanel = new JPanel(new FlowLayout(FlowLayout.LEFT));
        statusLabel = new JLabel("服务器状态：未启动");
        statusLabel.setFont(new Font("Microsoft YaHei UI", Font.BOLD, 14));
        statusPanel.add(statusLabel);
        
        onlineCountLabel = new JLabel("总连接数: 0 | 已登录: 0");
        onlineCountLabel.setFont(new Font("Microsoft YaHei UI", Font.BOLD, 12));
        onlineCountLabel.setForeground(Color.BLUE);
        statusPanel.add(Box.createHorizontalStrut(20));
        statusPanel.add(onlineCountLabel);
        
        topPanel.add(statusPanel, BorderLayout.WEST);
        mainPanel.add(topPanel, BorderLayout.NORTH);
        
        // 中间区域：只显示在线用户列表
        JPanel centerPanel = new JPanel(new BorderLayout());
        centerPanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
        
        // 在线用户列表
        JPanel usersPanel = new JPanel(new BorderLayout());
        JLabel usersLabel = new JLabel("在线用户列表");
        usersLabel.setFont(new Font("Microsoft YaHei UI", Font.BOLD, 14));
        usersPanel.add(usersLabel, BorderLayout.NORTH);
        onlineUsersArea = new JTextArea();
        onlineUsersArea.setEditable(false);
        onlineUsersArea.setFont(new Font("Consolas", Font.PLAIN, 12));
        onlineUsersArea.setBackground(new Color(245, 245, 245));
        JScrollPane usersScrollPane = new JScrollPane(onlineUsersArea);
        usersPanel.add(usersScrollPane, BorderLayout.CENTER);
        
        centerPanel.add(usersPanel, BorderLayout.CENTER);
        mainPanel.add(centerPanel, BorderLayout.CENTER);
        
        // 底部按钮区域
        JPanel bottomPanel = new JPanel(new FlowLayout());
        startButton = new JButton("启动");
        startButton.setPreferredSize(new Dimension(100, 35));
        startButton.addActionListener(e -> startServer());
        shutdownButton = new JButton("关闭");
        shutdownButton.setPreferredSize(new Dimension(100, 35));
        shutdownButton.setEnabled(false);
        shutdownButton.addActionListener(e -> shutdownServer());
        
        godModeButton = new JButton("开启上帝视角");
        godModeButton.setPreferredSize(new Dimension(150, 35));
        godModeButton.setForeground(Color.RED);
        godModeButton.setFont(new Font("Microsoft YaHei UI", Font.BOLD, 12));
        godModeButton.addActionListener(e -> openGodMode());
        
        bottomPanel.add(startButton);
        bottomPanel.add(shutdownButton);
        bottomPanel.add(Box.createHorizontalStrut(20));
        bottomPanel.add(godModeButton);
        mainPanel.add(bottomPanel, BorderLayout.SOUTH);
        
        add(mainPanel);
        
        // 初始化在线用户显示
        updateOnlineUsersDisplay();
    }
    
    /**
     * 启动定时刷新
     */
    private void startRefreshTimer() {
        if (refreshTimer != null) {
            refreshTimer.stop();
        }
        refreshTimer = new Timer(2000, e -> updateOnlineUsersDisplay()); // 每2秒刷新一次
        refreshTimer.start();
    }
    
    /**
     * 停止定时刷新
     */
    private void stopRefreshTimer() {
        if (refreshTimer != null) {
            refreshTimer.stop();
            refreshTimer = null;
        }
    }
    
    /**
     * 打开上帝视角窗口
     */
    private void openGodMode() {
        SwingUtilities.invokeLater(() -> {
            GodModePanel godModePanel = new GodModePanel(this);
            godModePanel.setVisible(true);
        });
    }
    
    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> {
            new ATMServer().setVisible(true);
        });
    }
}

